﻿using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZhonTai.Admin.Core.Attributes;
using ZhonTai.Admin.Core.Consts;
using ZhonTai.Admin.Tools.Cache;
using ZhonTai.Industry.Contracts.Core.Enums;
using ZhonTai.Industry.Contracts.Core.Model;
using ZhonTai.Industry.Core.Consts;
using ZhonTai.Industry.Core.Enums;
using ZhonTai.Industry.Domain.ReworkDefectRecord;
using ZhonTai.Industry.Domain.RouteDetail;
using ZhonTai.Industry.Domain.WorkStationRecord;

namespace ZhonTai.Industry.Removable.CraftGather.Query
{
    /// <summary>
    /// 查询操作
    /// </summary>
    [InjectTransient]
    public class QueryHandle : WorkExecuteBase
    {
        private readonly ICacheTool _cache;
        private IWorkStationRecordRepository _stationRecordRepository;
        private IReworkDefectRecordRepository _reworkDefectRecordRepository;

        public QueryHandle(ICacheTool cacheTool,
            IWorkStationRecordRepository stationRecordRepository,
            IReworkDefectRecordRepository reworkDefectRecordRepository)
        {
            _stationRecordRepository = stationRecordRepository;
            _reworkDefectRecordRepository = reworkDefectRecordRepository;
            _cache = cacheTool;
        }

        public override async Task ExecuteAsync(PushContent content)
        {
            try
            {
                //设置查询时间
                await _cache.SetAsync(CacheKey.QueryStartTime + content.StationId, DateTime.Now);
                //查询主条码
                string? masterCode = content.Plc.GetValue<string>(OffsetConsts.QueryMasterCode);
                if (masterCode == "")
                {
                    var result = await content.Plc.WriteValueAsync(0, (short)SearchResultEnum.EmptyMasterCode);
                    if (result.IsSuccess)
                    {
                        logger.Warn($"查询请求：工站【{content.OPCode}】条码不存在,回复成功！");
                    }
                    return;
                }
                SearchResultEnum searchResult = await ProcessVerificationAsync(content, masterCode);
                var writeResult = await content.Plc.WriteValueAsync(0, (short)searchResult);
                if (writeResult.IsSuccess)
                {
                    logger.Info($"查询请求：条码【{masterCode}】工站【{content.OPCode}】回复【{searchResult}】写入成功");
                }
            }
            catch (Exception ex)
            {
                var writeResult = await content.Plc.WriteValueAsync(0, (short)SearchResultEnum.SearchError);
                if (writeResult.IsSuccess)
                {
                    logger.Error($"工站【{content.OPCode}】查询错误，原因:{ex.Message},回复写入成功");
                }
            }
        }

        /// <summary>
        /// 工艺校验
        /// </summary>
        /// <param name="currentOpCode">当前工位</param>
        /// <param name="barCode">产品码</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private async Task<SearchResultEnum> ProcessVerificationAsync(PushContent ship, string? barCode)
        {
            long stationId = ship.StationId;
            string currentOpCode = ship.OPCode;
            var isVerify = await _cache.GetAsync<bool>(CacheKey.VerifyStatus + stationId);
            if (!isVerify)
            {
                return SearchResultEnum.AllowWork;
            }
            try
            {
                RouteDetailEntity? routeDetail = await _cache.GetAsync<RouteDetailEntity?>(CacheKey.ProductVerify + stationId);
                if (routeDetail == null)
                {
                    throw new Exception($"查询请求：条码【{barCode}】工站【{currentOpCode}】工艺路线为空！");
                }

                //返修操作
                if (routeDetail.StationRole == StationRoleEnum.Repair)
                {
                    return await RepairStationAsync(ship, barCode);
                }

                //上线操作
                if (routeDetail.StationRole == StationRoleEnum.Online)
                {
                    await OnlineStationAsync();
                }

                //下线操作
                if (routeDetail.StationRole == StationRoleEnum.Offline)
                {
                    await OfflineStationAsync();
                }

                //验证上道工序
                if (routeDetail.IsVerifyLast)
                {
                    long[]? verifyRules = JsonConvert.DeserializeObject<long[]>(routeDetail.VerifyRule);
                    var upperReslut = await _stationRecordRepository.Select.Where(w => w.ProductCode == barCode && verifyRules.Contains(w.StationId) && w.Result == "OK").Take(1).AnyAsync();
                    if (upperReslut)
                    {
                        logger.Warn($"查询请求：条码【{barCode}】工站【{currentOpCode}】上工站未加工或存在NG！");
                        return SearchResultEnum.UpperWorkNG;
                    }
                }

                //自身重复性验证
                if (routeDetail.IsVerifySelf)
                {
                    long verifyCount = await _stationRecordRepository.Select.Where(w => w.ProductCode == barCode && w.StationId == routeDetail.StationId && w.Result == "NG").Take(routeDetail.VerifyCount).CountAsync();
                    if (verifyCount >= routeDetail.VerifyCount)
                    {
                        logger.Warn($"查询请求：条码【{barCode}】工站【{currentOpCode}】超出当前设定的重复性验证次数！");
                        return SearchResultEnum.NotAllowWork;
                    }
                }
                else
                {
                    var currentResult = await _stationRecordRepository.Select.Where(w => w.ProductCode == barCode && w.StationId == routeDetail.StationId && w.Result == "OK").Take(1).AnyAsync();
                    if (currentResult)
                    {
                        logger.Warn($"查询请求：条码【{barCode}】工站【{currentOpCode}】本工站已加工且OK！");
                        return SearchResultEnum.CurrentWorked;
                    }
                }

                return SearchResultEnum.AllowWork;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 返修操作
        /// </summary>
        private async Task<SearchResultEnum> RepairStationAsync(PushContent push, string? barCode)
        {
            var reworkDefectRecord = await _reworkDefectRecordRepository.Where(w => w.ProductCode == barCode && w.CurrentStatus == 1).Take(1).ToOneAsync();
            if (reworkDefectRecord == null)
            {
                logger.Warn($"返修查询请求：条码【{barCode}】工站【{push.OPCode}】当前条码未存在NG信息！");
                return SearchResultEnum.NotAllowWork;
            }
            short plcStation = StationAvatar(reworkDefectRecord.FirstStationId);
            //未找到工站对应代号
            if (plcStation == -1)
            {
                logger.Warn($"返修查询请求：条码【{barCode}】工站【{push.OPCode}】当前NG工站代号【{reworkDefectRecord.FristStationCode}】未找到PLC对应工站代号！");
                return SearchResultEnum.NotAllowWork;
            }
            var result = await push.Plc.WriteValueAsync(4, plcStation);
            if (result.IsSuccess)
            {
                reworkDefectRecord.CurrentStatus = 2;
                await _reworkDefectRecordRepository.UpdateAsync(reworkDefectRecord);
                logger.Info($"返修查询请求：条码【{barCode}】工站【{push.OPCode}】返修写入NG工站【{reworkDefectRecord.FristStationCode}】成功！");
            }
            return SearchResultEnum.AllowWork;
        }

        /// <summary>
        /// 上线操作
        /// </summary>
        private async Task OnlineStationAsync()
        {
        }

        /// <summary>
        /// 下线操作
        /// </summary>
        private async Task OfflineStationAsync()
        {
        }
    }
}